package com.lz.yz.base.jop;

import com.lz.yz.base.entity.ReturnValue;
import com.lz.yz.base.util.Constant;
import com.lz.yz.config.dao.SysconfigMapper;
import com.lz.yz.member.service.PropertyInfoService;
import com.lz.yz.order.enumeration.OrderStatus;
import com.lz.yz.order.enumeration.OrderType;
import com.lz.yz.order.enumeration.TurnoversType;
import com.lz.yz.order.service.TurnoversService;
import com.lz.yz.outing.config.ConstantConfig;
import com.lz.yz.outing.enumeration.SettingType;
import com.lz.yz.outing.service.WechatService;
import com.lz.yz.reward.bean.RewardBean;
import com.lz.yz.reward.dao.RewardMapper;
import com.lz.yz.reward.entity.Reward;
import com.lz.yz.reward.enumeration.RewardStatus;
import com.lz.yz.reward.param.RewardParam;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.math.BigDecimal;
import java.util.List;

/**
 第一位，表示秒，取值0-59
 第二位，表示分，取值0-59
 第三位，表示小时，取值0-23
 第四位，日期天/日，取值1-31
 第五位，日期月份，取值1-12
 第六位，星期，取值1-7，星期一，星期二...，注：不是第1周，第二周的意思
 另外：1表示星期天，2表示星期一。
 第7为，年份，可以留空，取值1970-2099
 (*)星号：可以理解为每的意思，每秒，每分，每天，每月，每年...
 (?)问号：问号只能出现在日期和星期这两个位置，表示这个位置的值不确定，每天3点执行，所以第六位星期的位置，我们是不需要关注的，就是不确定的值。同时：日期和星期是两个相互排斥的元素，通过问号来表明不指定值。比如，1月10日，比如是星期1，如果在星期的位置是另指定星期二，就前后冲突矛盾了。
 (-)减号：表达一个范围，如在小时字段中使用“10-12”，则表示从10到12点，即10,11,12
 (,)逗号：表达一个列表值，如在星期字段中使用“1,2,4”，则表示星期一，星期二，星期四
 (/)斜杠：如：x/y，x是开始值，y是步长，比如在第一位（秒） 0/15就是，从0秒开始，每15秒，最后就是0，15，30，45，60    另：x/y，等同于0/y
 0 0 3 * * ?     每天3点执行
 0 5 3 * * ?     每天3点5分执行
 0 5 3 ? * *     每天3点5分执行，与上面作用相同
 0 5/10 3 * * ?  每天3点的 5分，15分，25分，35分，45分，55分这几个时间点执行
 0 10 3 ? * 1    每周星期天，3点10分 执行，注：1表示星期天
 0 10 3 ? * 1#3  每个月的第三个星期，星期天 执行，#号只能出现在星期的位置
 */
@Component
public class Jobs {

    public final static String cron =  "0 0 0 ? * 4";

    public final static long FIVE_Minute =  5 * 60 * 1000;

    private final Logger logger = LoggerFactory.getLogger(getClass());

    @Autowired
    RewardMapper rewardMapper;

    @Autowired
    PropertyInfoService propertyInfoService;

    @Autowired
    TurnoversService turnoversService;

    @Autowired
    SysconfigMapper sysconfigMapper;

    @Autowired
    WechatService wechatService;

    @Autowired
    ConstantConfig constantConfig;

    /**
     * 找大咖分红定时任务
     */
    @Scheduled(cron=cron)
    public void dividendsJob(){
        if(constantConfig.getSetting().equals(SettingType.LOCAL.value()))
            return;
        RewardParam param = new RewardParam();
        param.setOrderType(OrderType.GET.getStatusValue());
        param.setOrderStatus(OrderStatus.COMPLETE.getStatusValue());
        param.setRewardStatus(RewardStatus.COMPLETE.getStatusValue());

        List<RewardBean> priceModels = rewardMapper.queryGetOrderPrice(param);
        priceModels.forEach(priceModel->{
            param.setRewardId(priceModel.getRewardId());

            List<RewardBean> rewardBeans = rewardMapper.queryGetOrderPercentage(param);
            rewardBeans.forEach(rewardBean -> {
                //totalPrice*percentage/100
                BigDecimal price = priceModel.getTotalPrice().multiply(rewardBean.getPercentage()).divide(new BigDecimal(100));
                propertyInfoService.increaseBalance(rewardBean.getBuyerAccountId(),price);
                turnoversService.insert(rewardBean.getBuyerAccountId(), TurnoversType.DIVIDENDS, Constant.ADDITION,price,null);
                logger.info("DIVIDENDS:"+rewardBean.getBuyerAccountId()+":"+price);
            });
        });
    }

    /**
     * 找大咖回答后自动完成任务
     */
    @Scheduled(fixedDelay=FIVE_Minute)
    public void rewardCountdownJob(){
        if(constantConfig.getSetting().equals(SettingType.LOCAL.value()))
            return;
        RewardParam param = new RewardParam();
        param.setRewardStatus(RewardStatus.ANSWERED.getStatusValue());
        param.setRewardCountdown(Integer.valueOf(sysconfigMapper.getValueByKey(Constant.REWARD_COUNTDOWN_KEY)));
        List<RewardBean> rewardBeans = rewardMapper.queryAnswerByDate(param);
        rewardBeans.forEach(rewardBean -> {
            rewardMapper.updateByPrimaryKeySelective(new Reward(rewardBean.getRewardId(), RewardStatus.COMPLETE.getStatusValue()));

            BigDecimal answerPrice; //给大咖的钱
            if(rewardBean.getPrice().compareTo(rewardBean.getTotalPrice())==1){ //price>TotalPrice
                answerPrice = rewardBean.getTotalPrice();
            }else {
                answerPrice = rewardBean.getPrice();
            }
            propertyInfoService.increaseBalance(rewardBean.getAccountId(),answerPrice);
            turnoversService.insert(rewardBean.getAccountId(), TurnoversType.REWARD, Constant.ADDITION,answerPrice,null);

            logger.info("rewardCountdown:"+rewardBean.getRewardId());
        });
    }

    /**
     * 发布找大咖没找到自动取消任务
     */
    @Scheduled(fixedDelay=FIVE_Minute)
    public void rewardCancelJob(){
        if(constantConfig.getSetting().equals(SettingType.LOCAL.value()))
            return;
        RewardParam param = new RewardParam();
        param.setRewardStatus(RewardStatus.SERVICE.getStatusValue());
        List<RewardBean> ids = rewardMapper.queryNotFoundReward(param);
        ids.forEach(id->{
            try {
                //退款操作
                int rid = id.getRewardId();
                String sponsorOrderNo = rewardMapper.selectByPrimaryKey(rid).getOrderNo(); //发起人订单
                if(sponsorOrderNo!=null){
                    //发布人退款
                    ReturnValue returnValue = wechatService.wechatPayRefund(sponsorOrderNo);
                    if(returnValue.getCode()==200){
                        param.setOrderType(OrderType.REWARD.getStatusValue());
                        param.setOrderStatus(OrderStatus.COMPLETE.getStatusValue());
                        param.setRewardId(rid);

                        logger.info("sponsorWechatPayRefund:"+rid+",orderNo:"+sponsorOrderNo);
                        //所有参与过众筹的人退款
                        rewardMapper.queryNotFoundRewardOrder(param).forEach(order-> {
                            logger.info("rewardWechatPayRefund:"+rid+",orderNo:"+order.getOrderNo());
                            wechatService.wechatPayRefund(order.getOrderNo());
                        });
                    }
                }
            } catch (Exception e) {
                logger.error(e.getMessage());
            }
        });
    }
}